/*
    This is a set of libraries to assist in OpenGl and Other Applications
    Copyright (C) 2008  The Modular Engine Team

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CONSOLEMODULE_H
#define CONSOLEMODULE_H

#include <vector>
#include <string>
#include "EngineCore.h"

#define CFUNCTOR(X, Y, ...) class X: public CFunctor, public Singleton<X> \
	{ \
	public: \
		__VA_ARGS__ \
		X() \
		{ \
			init(); \
			mFuncName = Y; \
		} \
		void operator () ();\
		void init(); \
	};

#define ADDCOMMAND(X) ConsoleModule::getSingleton().addCommand( &ModularEngine::X::getSingleton() ); 
#define NEWARG(X) mArgs.push_back( CArg( X ) );
#define ARG_N(X) mArgs[X].mfArg
#define ARG_S(X) mArgs[X].msArg

#undef CLASSDECL
#ifdef CONSOLEMODULE
	#define CLASSDECL __declspec(dllexport)
#else
	#pragma comment( lib, "ConsoleModule.lib" )
	#define CLASSDECL __declspec(dllimport)
#endif

namespace ModularEngine
{

	// currently these are defined in TestModule.h
	// TODO: probably be good if these were functors.
	//CLASSDECL void console( const char *str );
	CLASSDECL void console( std::string str );
	CLASSDECL void console( const char *str, ... );

	enum CArgType
	{
		C_NUMBER = 0,
		C_STRING,
		C_IPADDRESS,
		// C_,
		C_ERROR
	};

	class CLASSDECL CArg
	{
	public:
		CArg()
		{
		}

		CArg( CArgType a )
		{
			mArgType = a;
		}
		CArgType mArgType;
		double mfArg;
		std::string msArg;
		
	};

	// C(onsole)Functor is a functor for use in the console.
	// Because most of our functions are in classes this must be used.
	class CLASSDECL CFunctor
	{
	public:
		std::vector<CArg> mArgs;
		std::string mFuncName;
		virtual void operator () () = 0;		
	};

	class CLASSDECL ConsoleFunctor
	{
	public:
		virtual void operator () (char *str) = 0;
	};

	class CLASSDECL ConsoleModule: BASE(ConsoleModule)
	{
	protected:
		std::vector<std::string> splitCommand( std::string str );
		double toNumber(std::string str);
#if 0 
		CArgType parseArgType( std::string str );
#endif
	public:
		ConsoleFunctor *mfConsole;
		std::vector<CFunctor *> mConsoleFunctions;

		int initialize();
		int run();

		
		std::string sendCommand( std::string str );

		void addCommand( CFunctor *pFunc );
		
	};
}


#endif